package com.ikingtech.platform.service.system.user.service;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ikingtech.framework.sdk.base.model.PageResult;
import com.ikingtech.framework.sdk.organization.api.OrgUserApi;
import com.ikingtech.framework.sdk.organization.model.OrganizationManagerDTO;
import com.ikingtech.framework.sdk.organization.model.OrganizationUserDTO;
import com.ikingtech.framework.sdk.user.api.UserDeptApi;
import com.ikingtech.framework.sdk.user.api.UserPostApi;
import com.ikingtech.framework.sdk.user.model.UserDeptDTO;
import com.ikingtech.framework.sdk.user.model.UserPostDTO;
import com.ikingtech.framework.sdk.utils.Tools;
import com.ikingtech.platform.service.system.user.entity.UserDO;
import com.ikingtech.platform.service.system.user.entity.UserDeptDO;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author tie yan
 */
@Service
@RequiredArgsConstructor
public class OrgUserService implements OrgUserApi {

    private final UserRepository service;

    private final UserDeptRepository userDeptService;

    private final UserDeptApi userDeptApi;

    private final UserPostRepository userPostService;

    private final UserPostApi userPostApi;

    /**
     * 移动用户到父部门
     *
     * @param parentId 父部门编号
     * @param deptIds  当前部门编号集合
     */
    @Override
    public void moveUser(String parentId, List<String> deptIds) {
        if (Tools.Coll.isBlank(deptIds)) {
            return;
        }
        List<String> userIds = this.userDeptService.listUserIdByDeptIds(deptIds);
        if (Tools.Coll.isBlank(userIds)) {
            return;
        }
        List<String> existUserIds = this.userDeptService.listUserIdByDeptId(parentId);
        if (Tools.Coll.isBlank(userIds)) {
            return;
        }
        this.userDeptService.saveBatch(Tools.Coll.convertList(userIds, userId -> !existUserIds.contains(userId), id -> {
            UserDeptDO entity = new UserDeptDO();
            entity.setId(Tools.Id.uuid());
            entity.setUserId(id);
            entity.setDeptId(parentId);
            return entity;
        }));

        this.userDeptService.remove(Wrappers.<UserDeptDO>lambdaQuery().in(UserDeptDO::getDeptId, deptIds));
    }

    @Override
    public PageResult<OrganizationUserDTO> loadUserByDeptIds(Integer page, Integer rows, List<String> deptIds) {
        if (Tools.Coll.isBlank(deptIds)) {
            return PageResult.build();
        }
        List<String> userIds = this.userDeptService.listUserIdByDeptIds(deptIds);
        List<UserDeptDTO> departments = this.userDeptApi.loadByIds(this.userDeptService.listDeptIdByUserIds(userIds));
        List<UserPostDTO> posts = this.userPostApi.loadByIds(this.userPostService.listPostIdByUserIds(userIds));
        return this.service.listPageByIds(page, rows, userIds).convert(entity -> {
            OrganizationUserDTO orgUser = new OrganizationUserDTO();
            orgUser.setUserId(entity.getId());
            orgUser.setName(entity.getName());
            orgUser.setPhone(entity.getPhone());
            orgUser.setEmail(entity.getEmail());
            orgUser.setDepartments(Tools.Coll.convertList(departments, UserDeptDTO::getDeptName));
            orgUser.setPostsNames(Tools.Coll.convertList(posts, UserPostDTO::getPostName));
            return orgUser;
        });
    }

    @Override
    public List<String> loadDeptIdByUserId(String userId, String tenantCode) {
        return this.userDeptService.listObjs(Wrappers.<UserDeptDO>lambdaQuery().eq(UserDeptDO::getUserId, userId).eq(UserDeptDO::getTenantCode, tenantCode), String.class::cast);
    }

    @Override
    public List<OrganizationManagerDTO> loadManagers(List<String> userIds) {
        List<UserDO> entities = this.service.listByIds(userIds);
        return Tools.Coll.convertList(entities, entity -> {
            OrganizationManagerDTO manager = Tools.Bean.copy(entity, OrganizationManagerDTO.class);
            manager.setUserId(entity.getId());
            return manager;
        });
    }

    @Override
    public OrganizationManagerDTO loadManager(String userId) {
        UserDO entity = this.service.getById(userId);
        OrganizationManagerDTO manager = Tools.Bean.copy(entity, OrganizationManagerDTO.class);
        manager.setUserId(entity.getId());
        return manager;
    }

    @Override
    public Map<String, Integer> getUserCount(List<String> deptIds) {
        if (Tools.Coll.isBlank(deptIds)) {
            return new HashMap<>();
        }
        List<UserDeptDO> userDeptEntities = this.userDeptService.listByDeptIds(deptIds);
        Map<String, List<UserDeptDO>> userDeptMap = Tools.Coll.convertGroup(userDeptEntities, UserDeptDO::getDeptId);

        Map<String, Integer> result = new HashMap<>(userDeptMap.size());
        userDeptMap.forEach((deptId, entities) -> result.put(deptId, entities.size()));
        return result;
    }
}
